package it.unicam.cs.cosy.bioshape.gui;

import hermesV3.util.HermesLogger;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;

/**
 * Handles GUI load/save tasks, i.e. the loading and the saving of simulation
 * input.
 * 
 * @author Federico Buti
 */
public class IOHandler {

	/** static file chooser called from different component of the software */
	volatile static JFileChooser c;

	/**
	 * Saves the currently selected simulation XML and updates the GUI to show
	 * that the saving was successful.
	 * 
	 * @param dash
	 *            The {@code DashBoard} currently selected.
	 * @param check
	 *            A flag, {@code true} if we want to show the file choosing
	 *            panel. Used for the "save as" command, in which we want to
	 *            save a copy of a simulation.
	 * @return {@code true} if the saving process is successful, {@code false}
	 *         otherwise.
	 */
	static boolean save(DashBoard dash, boolean check) {
		if (dash.getFile() != null && !check)
			return savingOperations(dash);
		c.setSelectedFile(new File(dash.getTitle()));
		int returnVal = c.showSaveDialog(null);
		if (returnVal == JFileChooser.CANCEL_OPTION)
			return false;
		// verify filename status...
		String fileName = c.getSelectedFile().getName();
		// takes the path
		String path = c.getCurrentDirectory().getAbsolutePath();
		path = path + File.separator + fileName;
		path = path.endsWith(".xml") ? path : path + ".xml";
		File saveFile;
		saveFile = new File(path);
		dash.setFile(saveFile);
		System.out.println(saveFile.getAbsolutePath());
		// saving
		return savingOperations(dash);
	}

	/**
	 * Loads a previously saved simulation XML.
	 * 
	 * @param owner
	 *            A reference to the main frame of the simulator.
	 */
	static void open(Monitor owner) {
		c.setCurrentDirectory(new File("workspace"));
		int returnVal = c.showOpenDialog(owner);
		if (returnVal == JFileChooser.CANCEL_OPTION)
			return;
		owner.addTab(c.getSelectedFile());
	}

	/**
	 * Executes the saving process. If the specified {@code file} to which save
	 * does not exist, it is created. It is called by
	 * {@link #save(DashBoard, boolean)}. At the end of the saving operation, it
	 * also updates the corresponding {@code Dashboard},
	 * 
	 * @param d
	 *            The {@code DashBoard} which contains the file to save.
	 * @return {@code true} if the saving process is successful, {@code false}
	 *         otherwise.
	 * 
	 * @see #save(DashBoard, boolean)
	 */
	static boolean savingOperations(DashBoard d) {
		BufferedWriter bw = null;
		try {
			if (!d.getFile().exists())
				d.getFile().createNewFile();
			FileWriter fw = new FileWriter(d.getFile());
			bw = new BufferedWriter(fw);
			bw.write(d.getText());
			// everything ok
			d.setTitle(d.getFile().getName());
			d.setDirtyBit(false);
			d.updateTitle(false);
			return true;
		} catch (Exception e) {
			HermesLogger.log(HermesLogger.ERROR,
					"IOHandler - " + "An error occurred while "
							+ "saving file '" + d.getTitle() + "'!");
			d.setFile(null); // next time we will be prompt with the save
			// panel!
			return false;
		} finally {
			try {
				if (bw != null)
					bw.close();
			} catch (IOException e) {
				// DOES NOTHING
			}
		}
	}

	/** Called in a different thread to speed up application start up. */
	static void buildHandler() {
		c = new JFileChooser();
		FileNameExtensionFilter filter = new FileNameExtensionFilter(
				"XML file", "xml");
		c.setFileFilter(filter);
	}
}